package com.agriculture.service;

import com.agriculture.domain.Order;
import com.agriculture.utils.HttpUtil;
import com.alibaba.fastjson.JSON;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;

@Service
public class BlockchainService {

    private static final Logger logger = LoggerFactory.getLogger(BlockchainService.class);

    @Value("${system.fisco.trans.url}")
    private String fiscoTransUrl;

    @Value("${system.contract.register.Product.address}")
    private String productAddress;

    @Value("${system.contract.owner.address}")
    private String ownerAddress;

    @Value("${system.contract.register.Product.abi}")
    private String productAbi;

    private String formatAddress(String address) {
        if (address == null || address.isEmpty()) {
            logger.warn("Empty address provided");
            return "";
        }

        // 如果地址已经是正确的格式（0x + 40位十六进制），直接返回
        if (address.matches("^0x[0-9a-fA-F]{40}$")) {
            return address.toLowerCase();
        }

        // 移除0x前缀（如果有）
        String cleanAddress = address.startsWith("0x") ? address.substring(2) : address;
        
        // 如果是40位十六进制，添加0x前缀并返回
        if (cleanAddress.matches("^[0-9a-fA-F]{40}$")) {
            return "0x" + cleanAddress.toLowerCase();
        }

        logger.error("Invalid address format: {}", address);
        throw new IllegalArgumentException("Invalid address format. Address must be a 40-character hex string with optional 0x prefix");
    }

    @PostConstruct
    public void init() {
        logger.info("Initialized BlockchainService with:");
        logger.info("fiscoTransUrl: {}", fiscoTransUrl);
        
        // 设置正确的地址
        productAddress = "0x8827092053006bfa99162371b678971639a29134";
        ownerAddress = "0x197c31a6fd6e67a2fa52950f3d7522c1dfda8491";
        
        logger.info("Using addresses:");
        logger.info("Product address: {}", productAddress);
        logger.info("Owner address: {}", ownerAddress);
        logger.info("productAbi: {}", productAbi);
    }

    public String testCreateProduct(Map<String, Object> productInfo) {
        if (productInfo == null || productInfo.isEmpty()) {
            throw new IllegalArgumentException("产品信息不能为空");
        }

        // 构建完整的供应链信息
        Map<String, Object> supplyChainInfo = new HashMap<>();
        supplyChainInfo.put("product", productInfo);  // 产品信息
        supplyChainInfo.put("farmer", new HashMap<String, String>() {{  // 农户信息
            put("id", productInfo.get("farmerId").toString());
            put("name", productInfo.get("farmerName").toString());
            put("address", productInfo.get("farmerAddress").toString());
            put("certificate", productInfo.get("farmerCertificate").toString());
        }});
        supplyChainInfo.put("distributor", new HashMap<String, String>() {{  // 经销商信息
            put("id", productInfo.get("distributorId").toString());
            put("name", productInfo.get("distributorName").toString());
            put("address", productInfo.get("distributorAddress").toString());
            put("license", productInfo.get("distributorLicense").toString());
        }});
        supplyChainInfo.put("traceInfo", new HashMap<String, String>() {{  // 溯源信息
            put("productionDate", productInfo.get("productionDate").toString());
            put("batchNumber", productInfo.get("batchNumber").toString());
            put("processingDate", productInfo.get("processingDate").toString());
            put("distributionDate", productInfo.get("distributionDate").toString());
        }});

        logger.info("Converted supplyChainInfo: {}", JSON.toJSONString(supplyChainInfo));
        
        Map<String, Object> params = new HashMap<>();
        params.put("groupId", 1);
        params.put("user", formatAddress(ownerAddress));
        params.put("contractAddress", formatAddress(productAddress));
        params.put("funcName", "updateProductInfo");
        params.put("contractAbi", JSON.parseArray(productAbi));
        params.put("funcParam", Collections.singletonList(JSON.toJSONString(supplyChainInfo)));
        
        logger.info("Request body: {}", JSON.toJSONString(params));
        
        try {
            String response = HttpUtil.post(fiscoTransUrl, JSON.toJSONString(params));
            logger.info("创建产品成功: {}", response);
            return response;
        } catch (Exception e) {
            logger.error("Failed to create product. Request body: {}", JSON.toJSONString(params), e);
            throw new RuntimeException("创建产品失败: " + e.getMessage());
        }
    }

    public String testGetProductInfo(String productAddress) {
        if (productAddress == null || productAddress.isEmpty()) {
            throw new IllegalArgumentException("产品地址不能为空");
        }

        Map<String, Object> params = new HashMap<>();
        params.put("groupId", 1);
        params.put("user", formatAddress(ownerAddress));
        params.put("contractAddress", formatAddress(productAddress));
        params.put("funcName", "info");
        params.put("contractAbi", JSON.parseArray(productAbi));
        params.put("funcParam", new ArrayList<>());
        
        logger.info("Getting product info for address: {}", productAddress);
        logger.info("Request params: {}", JSON.toJSONString(params));
        
        try {
            String response = HttpUtil.post(fiscoTransUrl, JSON.toJSONString(params));
            logger.info("获取产品信息成功: {}", response);
            return response;
        } catch (Exception e) {
            logger.error("获取产品信息失败. Request params: {}", JSON.toJSONString(params), e);
            throw new RuntimeException("获取产品信息失败: " + e.getMessage());
        }
    }

    public String testGetChainStatus() {
        Map<String, Object> params = new HashMap<>();
        params.put("groupId", 1);
        params.put("user", formatAddress(ownerAddress));
        params.put("contractName", "AgricultureSupplyChain");
        params.put("contractAddress", formatAddress(productAddress));
        params.put("funcName", "getStatus");
        params.put("contractAbi", JSON.parseArray(productAbi));
        params.put("funcParam", Collections.emptyList());
        
        try {
            String response = HttpUtil.post(fiscoTransUrl, JSON.toJSONString(params));
            logger.info("获取链状态成功: {}", response);
            return response;
        } catch (Exception e) {
            logger.error("获取链状态失败", e);
            throw new RuntimeException("获取链状态失败: " + e.getMessage());
        }
    }

    public String testUpdateProductInfo(String productAddress, String newInfo) {
        if (productAddress == null || productAddress.isEmpty()) {
            throw new IllegalArgumentException("产品地址不能为空");
        }
        if (newInfo == null || newInfo.isEmpty()) {
            throw new IllegalArgumentException("新的产品信息不能为空");
        }

        Map<String, Object> params = new HashMap<>();
        params.put("groupId", 1);
        params.put("user", formatAddress(ownerAddress));
        params.put("contractName", "Product");
        params.put("contractAddress", formatAddress(productAddress));
        params.put("funcName", "updateProductInfo");
        params.put("contractAbi", JSON.parseArray(productAbi));
        params.put("funcParam", Collections.singletonList(newInfo));
        
        logger.info("Updating product info - Address: {}, New Info: {}", productAddress, newInfo);
        
        try {
            String response = HttpUtil.post(fiscoTransUrl, JSON.toJSONString(params));
            logger.info("更新产品信息成功: {}", response);
            return response;
        } catch (Exception e) {
            logger.error("更新产品信息失败. Request params: {}", JSON.toJSONString(params), e);
            throw new RuntimeException("更新产品信息失败: " + e.getMessage());
        }
    }

    public String testCallContract(String contractAddress, String funcName, Map<String, String> params) {
        if (contractAddress == null || contractAddress.isEmpty()) {
            throw new IllegalArgumentException("合约地址不能为空");
        }
        if (funcName == null || funcName.isEmpty()) {
            throw new IllegalArgumentException("方法名不能为空");
        }

        Map<String, Object> requestParams = new HashMap<>();
        requestParams.put("groupId", 1);
        requestParams.put("user", formatAddress(ownerAddress));
        requestParams.put("contractAddress", formatAddress(contractAddress));
        requestParams.put("funcName", funcName);
        requestParams.put("contractAbi", JSON.parseArray(productAbi));
        requestParams.put("funcParam", Collections.singletonList(JSON.toJSONString(params)));
        
        try {
            String response = HttpUtil.post(fiscoTransUrl, JSON.toJSONString(requestParams));
            logger.info("调用合约成功: {}", response);
            return response;
        } catch (Exception e) {
            logger.error("调用合约失败", e);
            throw new RuntimeException("调用合约失败: " + e.getMessage());
        }
    }
} 